// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <optional>
#include <string>

#include <turbo/utility/status.h>
#include <nebula/version.h>  // IWYU pragma: export
#include <turbo/base/macros.h>

namespace nebula {

    struct BuildInfo {
      /// The packed version number, e.g. 1002003 (decimal) for Nebula 1.2.3
      int version;
      /// The "major" version number, e.g. 1 for Nebula 1.2.3
      int version_major;
      /// The "minor" version number, e.g. 2 for Nebula 1.2.3
      int version_minor;
      /// The "patch" version number, e.g. 3 for Nebula 1.2.3
      int version_patch;
      /// The version string, e.g. "1.2.3"
      std::string version_string;
      std::string so_version;
      std::string full_so_version;

      /// The CMake compiler identifier, e.g. "GNU"
      std::string compiler_id;
      std::string compiler_version;
      std::string compiler_flags;

      /// The git changeset id, if available
      std::string git_id;
      /// The git changeset description, if available
      std::string git_description;
      std::string package_kind;

      /// The uppercase build type, e.g. "DEBUG" or "RELEASE"
      std::string build_type;
    };

    struct RuntimeInfo {
      /// The enabled SIMD level
      ///
      /// This can be less than `detected_simd_level` if the NEBULA_USER_SIMD_LEVEL
      /// environment variable is set to another value.
      std::string simd_level;

      /// The SIMD level available on the OS and CPU
      std::string detected_simd_level;

      /// Whether using the OS-based timezone database
      /// This is set at compile-time.
      bool using_os_timezone_db;

      /// The path to the timezone database; by default None.
      std::optional<std::string> timezone_db_path;
    };

    /// \brief Get runtime build info.
    ///
    /// The returned values correspond to exact loaded version of the Nebula library,
    /// rather than the values frozen at application compile-time through the `NEBULA_*`
    /// preprocessor definitions.
    TURBO_EXPORT
    const BuildInfo& GetBuildInfo();

    /// \brief Get runtime info.
    ///
    TURBO_EXPORT
    RuntimeInfo GetRuntimeInfo();

    struct GlobalOptions {
      /// Path to text timezone database. This is only configurable on Windows,
      /// which does not have a compatible OS timezone database.
      std::optional<std::string> timezone_db_path;
    };

    TURBO_EXPORT
    turbo::Status Initialize(const GlobalOptions& options) noexcept;

}  // namespace nebula
